﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<list>
#include<map>
#include"list.h"
#include<assert.h>
#include<algorithm>
#include<functional>
using namespace std;
//struct Point {
//	int x;
//	int y;
//};
//int main()
//{
//	int a[] = { 1,2,3,4 };
//	Point p = { 1,1 };
//	return 0;
//}

//class Date
//{
//public:
//	Date(int year, int month, int day)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	Date x(2023, 11, 30);
//
//	Date y = { 2023,11,30 };
//	Date z{ 2023,11,30 };
//	return 0;
//}

//int main()
//{
//	vector<int>v = { 0,1,2,3,4 };
//	list<int>l = { 2,3,5,6,30 };
//	map<string, string>mp = { {"string","字符串"} ,{"sort","排序"} };
//	for (auto x : v)
//	{
//		cout << x << " ";
//	}
//	cout << endl;
//
//	for (auto x : l)
//	{
//		cout << x << " ";
//	}
//	cout << endl;
//
//	for (auto x : mp)
//	{
//		cout << x.first << ":" << x.second << endl;
//	}
//
//	v = { 1,2,34,5,6 };
//	for (auto x : v)
//	{
//		cout << x << " ";
//	}
//	cout << endl;
//	return 0;
//}


//namespace zxws
//{
//    template<class T>
//    class vector
//    {
//    public:
//        typedef T* iterator;
//        vector() = default;
//
//        vector(int n, const T& value = T())
//        {
//            reserve(n);
//            while (n--)
//            {
//                push_back(value);
//            }
//        }
//            
//        vector(initializer_list<T> l)
//        {
//            reserve(l.size());
//            for(auto& e:l)
//            {
//                push_back(e);
//            }
//        }
//
//        vector(const vector<T>& v)
//        {
//            reserve(v.capacity());
//            for (auto& x : v)
//            {
//                push_back(x);
//            }
//        }
//
//        vector<T>& operator= (vector<T> v)
//        {
//            swap(v);
//            return *this;
//        }
//
//        vector<T>& operator= (initializer_list<T> l)
//        {
//            vector<T>tmp(l);
//            swap(tmp);
//            return *this;
//        }
//
//        void swap(vector<T>& v)
//        {
//            std::swap(_start, v._start);
//            std::swap(_finish, v._finish);
//            std::swap(_endOfStorage, v._endOfStorage);
//        }
//
//        ~vector()
//        {
//            if (_start)
//            {
//                delete[] _start;
//                _start = _finish = _endOfStorage = nullptr;
//            }
//        }
//        void push_back(const T& x)
//        {
//            if (_finish == _endOfStorage)
//            {
//                reserve(capacity() == 0 ? 4 : capacity() * 2);
//            }
//            *_finish = x;
//            _finish++;
//        }
//
//        size_t capacity() const
//        {
//            return _endOfStorage - _start;
//        }
//        size_t size() const
//        {
//            return _finish - _start;
//        }
//        void reserve(size_t n)
//        {
//            if (n > capacity())
//            {
//                size_t sz = size();
//                T* tmp = new T[n];
//                if (_start)
//                {
//                    for (size_t i = 0; i < sz; i++)
//                    {
//                        tmp[i] = _start[i];
//                    }
//                    delete[] _start;
//                }
//
//                _start = tmp;
//                _finish = _start + sz;
//                _endOfStorage = _start + n;
//            }
//        }
//        T& operator[](size_t pos)
//        {
//            assert(pos < size());
//            return _start[pos];
//        }
//    private:
//        iterator _start = nullptr;// 指向数据块的开始
//        iterator _finish = nullptr; // 指向有效数据的尾
//        iterator _endOfStorage = nullptr; // 指向存储容量的尾
//    };
//
//    void test()
//    {
//        vector<int>v{ 1,22,3,6,7,5 };
//        for (int i = 0; i < v.size(); i++)
//            cout << v[i] << " ";
//        cout << endl;
//        v = { 2,56,8,9,1,2 };
//        for (int i = 0; i < v.size(); i++)
//            cout << v[i] << " ";
//        cout << endl;
//    }
//}
//
//int main()
//{
//    zxws::test();
//    return 0;
//}


//int main()
//{
//	int x = 1;
//	double y = 2.2;
//	decltype(x * y) ret = x * y;//这个用法和auto没啥区别
//	vector<decltype(x * y)>v;//这里只能用decltype
//	//vector<auto>v,错误写法
//	return 0;
//}

//int main()
//{
//	// 以下的p、b、c、*p都是左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = 2;
//	// 以下几个是对上面左值的左值引用
//	int*& rp = p;
//	int& rb = b;
//	const int& rc = c;
//	int& pval = *p;
//	return 0;
//}

//int main()
//{
//	double x = 1.1, y = 2.2;
//	// 以下几个都是常见的右值
//	10;
//	x + y;
//	fmin(x, y);
//	// 以下几个都是对右值的右值引用
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	// 这里编译会报错：error C2106: "=": 左操作数必须为左值
//	//10 = 1;
//	//x + y = 1;
//	//fmin(x, y) = 1;
//	return 0;
//}
//
//int main()
//{
//	double&& x = 1.1;
//	const double&& y = 1.2;
//	x = 1.3;
//	y = 1.5;//错误
//	return 0;
//}

//int main()
//{
//	//左值引用可以引用右值，但要加const修饰，本质是权限的放大问题
//	//int& t1 = 1;//不行
//	const int& t2 = 1;
//
//	//右值引用无法引用左值
//	int x = 0;
//	//int&& rx = x;
//	//const int&& rx = x;
//	int&& rx = move(x);//但可以引用被move以后的左值
//	return 0;
//}
//
//zxws::string test()
//{
//	zxws::string str = "hello world";
//	//...
//	return str;
//}


//class Person
//{
//public:
//    Person(const char* name = "", int age = 0)
//        :_name(name)
//        , _age(age)
//    {}
//
//    //Person(const Person& p)
//    //    :_name(p._name)
//    //    ,_age(p._age)
//    //{}
//
//    //Person& operator=(const Person& p)
//    //{
//    //    if(this != &p)
//    //    {
//    //        _name = p._name;
//    //        _age = p._age;
//    //    }
//    //    return *this;
//    //}
//
//    //Person(Person&& x) = default;
//    //Person(Person& x) = delete;
//
//
//    ~Person()
//    {}
//private:
//    zxws::string _name;
//    int _age;
//};
//
//int main()
//{
//    Person s1;
//    Person s2 = s1;
//    Person s3 = std::move(s1);
//    Person s4;
//    s4 = std::move(s2);
//    return 0;
//}

//class A {
//public:
//    A(){}
//    A(const A& a) = delete;
//    ~A() = default;
//
//    //final 和 override 在多态中讲过
//};

//int main()
//{
//	zxws::string s = test();
//	return 0;
//}

//template<class _Ty>
//inline typename remove_reference<_Ty>::type&& move(_Ty&& _Arg) _NOEXCEPT
//{
//    // forward _Arg as movable
//    return ((typename remove_reference<_Ty>::type&&)_Arg);
//}



//int main()
//{
//    string s1("hello world");
//    // 这里s1是左值，调用的是拷贝构造
//    string s2(s1);
//    // 这里我们把s1 move处理以后, 会被当成右值，调用移动构造
//    // 但是这里要注意，一般是不要这样用的，因为我们会发现s1的
//    // 资源被转移给了s3，s1被置空了。
//    string s3(std::move(s1));
//    return 0;
//}

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<class T>
//void Perfect(T&& x)
//{
//    Fun(forward<T>(x));
//}
//
//int main()
//{
//    int x = 1;
//    Perfect(x);
//    const int y = 0;
//    Perfect(y);
//    Perfect(move(x));
//    Perfect(move(y));
//    return 0;
//}



// Args是一个模板参数包，args是一个函数形参参数包
// 声明一个参数包Args...args，这个参数包中可以包含0到任意个模板参数。
//void _ShowList()
//{
//    cout << endl;
//}
//
//template <class T, class ...Args>
//void _ShowList(T val, Args...args)
//{
//    cout << val << " ";
//    _ShowList(args...);
//}
//
//template <class ...Args>
//void ShowList(Args... args)
//{
//    _ShowList(args...);
//}

//
//template <class T>
//int Print(T val)
//{
//    cout << val << " ";
//    return 0;
//}
//template <class ...Args>
//void ShowList(Args... args)
//{
//    int a[] = { Print(args)... };
//    cout << endl;
//}
//
//int main()
//{
//    ShowList(1, 2.2, 'x', "hhhh");
//    return 0;
//}


namespace zxws
{
	class string
	{
	public:
		typedef char* iterator;

	public:

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(strlen(str))
		{
			cout << "构造函数" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		string(const string& s)
			:_size(s._size)
			, _capacity(s._size)
		{
			cout << "拷贝构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, s._str);
		}

		string(string&& tmp)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "移动构造" << endl;
			swap(tmp);
		}

		string& operator=(string&& tmp)
		{
			//cout<<"string& operator=(string&& tmp)"<<endl;
			swap(tmp);
			return *this;
		}

		string& operator=(const string& s)
		{
			if (*this != s)
			{
				char* tmp = new char[s._capacity + 1];
				strcpy(tmp, s._str);
				delete[] _str;
				_str = tmp;
				_size = s._size;
				_capacity = s._capacity;
			}
			return *this;
		}


		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}

		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		void push_back(char c)
		{
			if (_size == _capacity) {
				reserve(_capacity ? 2 * _capacity : 4);
			}
			_str[_size++] = c;
			_str[_size] = '\0';
		}

		string& operator+=(char c)
		{
			push_back(c);
			return *this;
		}

		void append(const char* str)
		{
			size_t len = strlen(str);
			if (len + _size > _capacity) {
				reserve(len + _size);
			}
			strcat(_str, str);
			_size += len;
		}

		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}

		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}

		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		const char* c_str() const
		{
			return _str;
		}

		size_t size() const
		{
			return _size;
		}

		size_t capacity() const
		{
			return _capacity;
		}

		bool empty() const
		{
			return _size == 0;
		}

		void resize(size_t n, char c = '\0')
		{
			if (n < _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				reserve(n);
				for (int i = _size; i < n; i++)
				{
					_str[i] = c;
				}
				_str[n] = '\0';
				_size = n;
			}
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}

		char& operator[](size_t index)
		{
			assert(index < _size);
			return _str[index];
		}

		const char& operator[](size_t index)const
		{
			assert(index < _size);
			return _str[index];
		}


		bool operator<(const string& s)
		{
			return strcmp(_str, s._str) < 0;
		}

		bool operator<=(const string& s)
		{
			return *this < s || *this == s;
		}

		bool operator>(const string& s)
		{
			return !(*this <= s);
		}

		bool operator>=(const string& s)
		{
			return !(*this < s);
		}

		bool operator==(const string& s)
		{
			return strcmp(_str, s._str) == 0;
		}

		bool operator!=(const string& s)
		{
			return !(*this == s);
		}



		// 返回c在string中第一次出现的位置
		size_t find(char c, size_t pos = 0) const
		{
			assert(pos < _size);
			for (size_t i = pos; i < _size; i++) {
				if (_str[i] == c)
					return i;
			}
			return npos;
		}

		// 返回子串s在string中第一次出现的位置
		size_t find(const char* s, size_t pos = 0) const
		{
			char* p = strstr(_str + pos, s);
			return p ? p - _str : npos;
		}

		// 在pos位置上插入字符c/字符串str，并返回该字符的位置
		string& insert(size_t pos, char c)
		{
			assert(pos <= _size);
			if (_size == _capacity)
				reserve(_capacity ? 2 * _capacity : 4);
			for (size_t i = _size + 1; i > pos; i--)
			{
				_str[i] = _str[i - 1];//将\0也拷贝
			}
			_str[pos] = c;
			_size++;
			return *this;
		}

		string& insert(size_t pos, const char* str)
		{
			assert(pos <= _size);
			size_t len = strlen(str);
			if (len + _size > _capacity)
				reserve(len + _size);
			for (size_t i = _size + len, j = _size + 1; j > pos; j--, i--)
			{
				_str[i] = _str[j - 1];//将\0也拷贝
			}
			strncpy(_str + pos, str, len);
			return *this;
		}



		// 删除pos位置上的元素，并返回该元素的下一个位置
		string& erase(size_t pos, size_t len)
		{
			assert(pos < _size);
			if (pos + len > _size) {
				_str[pos] = '\0';
				_size = pos;
			}
			else {
				for (size_t i = pos + len; i <= _size; i++) {
					_str[i - len] = _str[i];
				}
				_size -= len;
			}
			return *this;
		}

	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
		static const int npos = -1;
	};
}
//int main()
//{
//	//zxws::string s;
//	zxws::list<pair<zxws::string, int>>l;
//	cout << endl;
//	l.emplace_back("string", 1);
//	cout << endl;
//	l.push_back(make_pair("string", 1));
//    return 0;
//}
//template <class ...Args>
//void ShowList(Args... args)
//{
//    //int a[] = { Print(args)... };
//	cout << sizeof...(args) << endl;
//    cout << endl;
//}
//
//int main()
//{
//    ShowList(1, 2.2, 'x', "hhhh");
//    return 0;
//}

class Person {
public:
	Person(int age,string name)
		:_age(age)
		,_name(name)
	{}
//private:
	int _age;
	string _name;
};

struct comp_age {
	bool operator()(const Person& x, const Person& y) {
		return x._age < y._age;
	}
};

struct comp_name {
	bool operator()(const Person& x, const Person& y) {
		return x._name < y._name;
	}
};

//int main()
//{
//	vector<Person>v = { {10,"zhangsan"},{40,"wangwu"},{20,"lisi"} };
//	auto f = [](const Person& x, const Person& y) {return x._age < y._age; };
//	comp_age cmp;
//	sort(v.begin(), v.end(), [](const Person& x, const Person& y){ return x._age < y._age; });
//	sort(v.begin(), v.end(), comp_age());
//	return 0;
//}


//
//int main()
//{
//	 //最简单的lambda表达式, 该lambda表达式没有任何意义
//	[] {};
//
//	 //省略参数列表和返回值类型，返回值类型由编译器推导为int
//	int a = 3, b = 4;
//	[=] {return a + 3; };
//
//	 //省略了返回值类型，无返回值类型
//	auto fun1 = [&](int c) {b = a + c; };
//	fun1(10);
//	cout << a << " " << b << endl;
//
//	 //各部分都很完善的lambda函数
//	auto fun2 = [=, &b](int c)->int {return b += a + c; };
//	cout << fun2(10) << endl;
//
//	 //复制捕捉x
//	int x = 10;
//	auto add_x = [x](int a) mutable { x *= 2; return a + x; };
//	cout << add_x(10) << endl;
//	return 0;
//}

class Rate
{
public:
	Rate(double rate) : _rate(rate)
	{}

	double operator()(double money, int year)
	{
		return money * _rate * year;
	}
private:
	double _rate;
};

//int main()
//{
//	Rate rate(0.1);//创建对象
//	rate(1000, 2);//调用operator()函数
//	cout << typeid(rate).name() << endl;
//	return 0;
//}

//void (*PF)();
//int main()
//{
//	auto f1 = [] {cout << "hello world" << endl; };
//	auto f2 = [] {cout << "hello world" << endl; };
//	f1();
//	f2();
//	cout << typeid(f1).name() << endl;
//	cout << typeid(f2).name() << endl;
//	// 此处先不解释原因，等lambda表达式底层实现原理看完后，大家就清楚了
//    //f1 = f2;// 编译失败--->提示找不到operator=()
//	// 允许使用一个lambda表达式拷贝构造一个新的副本
//	//auto f3(f2);
//	//f3();
//	// 可以将lambda表达式赋值给相同类型的函数指针
//	//PF = f2;
//	//PF();
//	return 0;
//}


template<class F, class T>
T useF(F f, T x)
{
	static int count = 0;
	cout << "count:" << ++count << endl;
	cout << "count:" << &count << endl;
	return f(x);
}
double f(double i)
{
	return i / 2;
}
struct Functor
{
	double operator()(double d)
	{
		return d / 3;
	}
};
//int main()
//{
//	// 函数名
//	cout << useF(f, 11.11) << endl;
//	// 函数对象
//	cout << useF(Functor(), 11.11) << endl;
//	// lamber表达式
//	cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;
//	return 0;
//}

//int main()
//{
//	// 函数名
//	function<double(double)> func1 = f;
//	cout << useF(func1, 11.11) << endl;
//	cout << typeid(func1).name() << endl;
//	 //函数对象
//	function<double(double)> func2 = Functor();
//	cout << useF(func2, 11.11) << endl;
//	cout << typeid(func2).name() << endl;
//
//	 //lamber表达式
//	function<double(double)> func3 = [](double d)->double { return d / 4; };
//	cout << useF(func3, 11.11) << endl;
//	cout << typeid(func3).name() << endl;
//
//	return 0;
//}


//int test(int x, int y)
//{
//	return x * 2 + y * 3;
//}
//
//int main()
//{
//	function<int(int)>fun1 = bind(test, 2, placeholders::_1);
//	cout << fun1(1) << endl;
//	function<int(int)>fun2 = bind(test, placeholders::_1, 2);
//	cout << fun2(1) << endl;
//
//	function<int(int,int)>fun3 = bind(test, placeholders::_2, placeholders::_1);
//	cout << fun3(2, 3) << endl;
//	return 0;
//}



//class Plus {
//public:
//	//static int ADD(int x, int y)
//	int ADD(int x, int y)
//	{
//		return x, y;
//	}
//	//static double ADD(double x, double y)
//	//{
//	//	return x + y;
//	//}
//};
//

int ADD(int x, int y)
{
	return x, y;
}
double ADD(double x, double y)
{
	return x + y;
}

int main()
{
	function<int(int, int)>func3 = (int(*)(int, int))ADD;
	function<double(double, double)>func4 = (double(*)(double, double))ADD;
	cout << func3(1, 2) << endl;
	cout << func4(1.1, 2.2) << endl;
	return 0;
}


//class Plus {
//public:
//	//static int ADD(int x, int y)
//	int ADDi(int x, int y)
//	{
//		return x, y;
//	}
//	static double ADDd(double x, double y)
//	{
//		return x + y;
//	}
//private:
//	int a = 0;
//
//};

//
//int main()
//{
//	Plus op;
//	function<int(Plus, int, int)>func1 = &Plus::ADDi;
//	cout << func1(op, 1, 2) << endl;
//	function<int(Plus*, int, int)>func2 = &Plus::ADDi;
//	cout << func2(&op, 1, 2) << endl;
//	function<double(double, double)>func3 = &Plus::ADDd;
//	cout << func3(1.1, 2.3) << endl;
//	return 0;
//}


//int main()
//{
//	function<int(int, int)>func1 = bind(&Plus::ADDi, Plus(), placeholders::_1, placeholders::_2);
//	cout << func1(1, 2) << endl;
//	//这种是不行的，右值不能被取地址！！！
//	//function<int(int, int)>func2 = bind(&Plus::ADDi, &Plus(), 1, 2);
//	//cout << func2(1, 2) << endl;
//
//	function<double(double, double)>func3 = bind(&Plus::ADDd, placeholders::_1, placeholders::_2);
//	cout << func3(1.1, 2.3) << endl;
//	return 0;
//}



//int main()
//{
//	function<int(int, int)>f = bind([](int x, int y) 
//		{return x + y; }, placeholders::_1, placeholders::_2);
//	cout<<f(1, 1) << endl;
//	return 0;
//}